package cn.zhentao.service.impl;

import cn.zhentao.mapper.MenuMapper;
import cn.zhentao.mapper.PermissionMapper;
import cn.zhentao.mapper.RolePermissionMapper;
import cn.zhentao.mapper.UserRoleMapper;
import cn.zhentao.pojo.Menu;
import cn.zhentao.pojo.Permission;
import cn.zhentao.pojo.RolePermission;
import cn.zhentao.pojo.UserRole;
import cn.zhentao.service.MenuService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
* @author xm166
* @description 针对表【menu(菜单权限表)】的数据库操作Service实现
* @createDate 2025-07-28 16:25:23
*/
@Service
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu>
    implements MenuService{

    @Autowired
    private MenuMapper menuMapper;

    @Autowired
    private PermissionMapper permissionMapper;

    @Autowired
    private RolePermissionMapper rolePermissionMapper;

    @Autowired
    private UserRoleMapper userRoleMapper;

    @Override
    public List<Menu> getMenuTree() {
        QueryWrapper<Menu> wrapper = new QueryWrapper<>();
        wrapper.eq("status", "0"); // 只查询正常状态的菜单
        wrapper.orderByAsc("parent_id", "order_num");
        List<Menu> allMenus = menuMapper.selectList(wrapper);

        return buildMenuTree(allMenus);
    }

    @Override
    public List<Menu> getMenusByParentId(Long parentId) {
        QueryWrapper<Menu> wrapper = new QueryWrapper<>();
        wrapper.eq("parent_id", parentId);
        wrapper.eq("status", "0");
        wrapper.orderByAsc("order_num");
        return menuMapper.selectList(wrapper);
    }

    @Override
    public List<Menu> getUserMenuTree(Long userId) {
        // 获取用户角色
        QueryWrapper<UserRole> userRoleWrapper = new QueryWrapper<>();
        userRoleWrapper.eq("id", userId);
        List<UserRole> userRoles = userRoleMapper.selectList(userRoleWrapper);

        if (userRoles.isEmpty()) {
            return new ArrayList<>();
        }

        List<Integer> roleIds = userRoles.stream()
                .map(UserRole::getRoleId)
                .collect(Collectors.toList());

        // 获取角色权限
        QueryWrapper<RolePermission> rolePermWrapper = new QueryWrapper<>();
        rolePermWrapper.in("role_id", roleIds);
        List<RolePermission> rolePermissions = rolePermissionMapper.selectList(rolePermWrapper);

        if (rolePermissions.isEmpty()) {
            return new ArrayList<>();
        }

        List<Long> permissionIds = rolePermissions.stream()
                .map(RolePermission::getPermissionId)
                .distinct()
                .collect(Collectors.toList());

        // 获取权限对应的菜单
        QueryWrapper<Permission> permWrapper = new QueryWrapper<>();
        permWrapper.in("permission_id", permissionIds);
        permWrapper.isNotNull("menu_id");
        List<Permission> permissions = permissionMapper.selectList(permWrapper);

        List<Long> menuIds = permissions.stream()
                .map(Permission::getMenuId)
                .distinct()
                .collect(Collectors.toList());

        if (menuIds.isEmpty()) {
            return new ArrayList<>();
        }

        // 获取菜单信息
        QueryWrapper<Menu> menuWrapper = new QueryWrapper<>();
        menuWrapper.in("menu_id", menuIds);
        menuWrapper.eq("status", "0");
        menuWrapper.orderByAsc("parent_id", "order_num");
        List<Menu> userMenus = menuMapper.selectList(menuWrapper);

        return buildMenuTree(userMenus);
    }

    @Override
    public List<Menu> getMenusByRoleId(Long roleId) {
        // 获取角色权限
        QueryWrapper<RolePermission> wrapper = new QueryWrapper<>();
        wrapper.eq("role_id", roleId);
        List<RolePermission> rolePermissions = rolePermissionMapper.selectList(wrapper);

        if (rolePermissions.isEmpty()) {
            return new ArrayList<>();
        }

        List<Long> permissionIds = rolePermissions.stream()
                .map(RolePermission::getPermissionId)
                .collect(Collectors.toList());

        // 获取权限对应的菜单
        QueryWrapper<Permission> permWrapper = new QueryWrapper<>();
        permWrapper.in("permission_id", permissionIds);
        permWrapper.isNotNull("menu_id");
        List<Permission> permissions = permissionMapper.selectList(permWrapper);

        List<Long> menuIds = permissions.stream()
                .map(Permission::getMenuId)
                .distinct()
                .collect(Collectors.toList());

        if (menuIds.isEmpty()) {
            return new ArrayList<>();
        }

        return menuMapper.selectBatchIds(menuIds);
    }

    @Override
    public IPage<Menu> getMenuPage(Page<Menu> page, String menuName, String status) {
        QueryWrapper<Menu> wrapper = new QueryWrapper<>();

        if (StringUtils.hasText(menuName)) {
            wrapper.like("menu_name", menuName);
        }

        if (StringUtils.hasText(status)) {
            wrapper.eq("status", status);
        }

        wrapper.orderByAsc("parent_id", "order_num");

        return menuMapper.selectPage(page, wrapper);
    }

    @Override
    public boolean existsByMenuName(String menuName, Long parentId) {
        QueryWrapper<Menu> wrapper = new QueryWrapper<>();
        wrapper.eq("menu_name", menuName);
        wrapper.eq("parent_id", parentId);
        return menuMapper.selectCount(wrapper) > 0;
    }

    @Override
    public boolean existsByPath(String path) {
        QueryWrapper<Menu> wrapper = new QueryWrapper<>();
        wrapper.eq("path", path);
        return menuMapper.selectCount(wrapper) > 0;
    }

    @Override
    public List<Menu> getEnabledMenus() {
        QueryWrapper<Menu> wrapper = new QueryWrapper<>();
        wrapper.eq("status", "0"); // 0表示正常状态
        wrapper.orderByAsc("parent_id", "order_num");
        return menuMapper.selectList(wrapper);
    }

    @Override
    public boolean deleteMenusByIds(List<Long> menuIds) {
        return menuMapper.deleteBatchIds(menuIds) > 0;
    }

    @Override
    public boolean updateMenuStatus(Long menuId, String status) {
        Menu menu = new Menu();
        menu.setMenuId(menuId);
        menu.setStatus(status);
        return menuMapper.updateById(menu) > 0;
    }

    @Override
    public List<Menu> buildMenuTree(List<Menu> menus) {
        List<Menu> rootMenus = new ArrayList<>();

        // 找出所有根菜单（parent_id为0或null）
        for (Menu menu : menus) {
            if (menu.getParentId() == null || menu.getParentId() == 0) {
                rootMenus.add(menu);
            }
        }

        // 为每个根菜单构建子菜单树
        for (Menu rootMenu : rootMenus) {
            buildChildMenus(rootMenu, menus);
        }

        return rootMenus;
    }

    private void buildChildMenus(Menu parentMenu, List<Menu> allMenus) {
        List<Menu> childMenus = new ArrayList<>();

        for (Menu menu : allMenus) {
            if (menu.getParentId() != null && menu.getParentId().equals(parentMenu.getMenuId())) {
                childMenus.add(menu);
            }
        }

        // 递归构建子菜单的子菜单
        for (Menu childMenu : childMenus) {
            buildChildMenus(childMenu, allMenus);
        }

        // 这里需要在Menu实体类中添加children字段来存储子菜单
        // parentMenu.setChildren(childMenus);
    }

    @Override
    public List<Long> getChildMenuIds(Long menuId) {
        List<Long> childIds = new ArrayList<>();

        QueryWrapper<Menu> wrapper = new QueryWrapper<>();
        wrapper.eq("parent_id", menuId);
        List<Menu> childMenus = menuMapper.selectList(wrapper);

        for (Menu childMenu : childMenus) {
            childIds.add(childMenu.getMenuId());
            // 递归获取子菜单的子菜单
            childIds.addAll(getChildMenuIds(childMenu.getMenuId()));
        }

        return childIds;
    }

    @Override
    public boolean hasChildMenus(Long menuId) {
        QueryWrapper<Menu> wrapper = new QueryWrapper<>();
        wrapper.eq("parent_id", menuId);
        return menuMapper.selectCount(wrapper) > 0;
    }
}




